import copy

from . import get_DeviceFactoryClasses

class DeviceFactory(object):
    def __init__(self):
        self.root_classes, self.type_classes = get_DeviceFactoryClasses()
        self.default_type = 'NormalDevice'
        
    def make(self, **kwargs):
        type_name = kwargs.get('type', self.default_type)
        base_name = kwargs.get('base')
        
        new_kwargs = kwargs.get('kwargs')
        
        base_cls = self.root_classes[base_name]
        type_cls = self.type_classes[type_name]
        
        cls_dict = base_cls.__dict__.copy()
        cls_dict.update(type_cls.__dict__.copy())
        cls_dict.update({'meta_base':base_cls})
        new_bases = (base_cls, ) + type_cls.__bases__
        new_cls = type(type_cls.__name__, new_bases, cls_dict)
        
        #new_cls = copy.deepcopy(type_cls)
        #new_cls.__bases__ = (base_cls, )
        
        obj = new_cls(base_cls, **new_kwargs)
        return obj
    
    def make_definition(self, **kwargs):
        new_kwargs = kwargs.get('kwargs')
        type_name = kwargs.get('type', self.default_type)
        
        obj = self.make(type=type_name, base='DefinedDevice', kwargs=new_kwargs)
        return obj
        
    def make_patched_from_defined(self, definition, **kwargs):
        type_name = definition.saved_class_name
        new_kwargs = definition._get_saved_attr()['attrs'].copy()
        del new_kwargs['id']
        new_kwargs.update({'_DefinedDevice_':definition})
        new_kwargs.update(kwargs)
        new_kwargs.update({'categories':definition.categories})
        obj = self.make(type=type_name, base='PatchedDevice', kwargs=new_kwargs)
        return obj
        
    def make_from_dict(self, d, **kwargs):
        type_name = d['saved_class_name']
        base_name = d['attrs']['base_class']
        kwargs.update({'deserialize':d})
        device = self.make(base=base_name, type=type_name, kwargs=kwargs)
        
        return device
